home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / VBSamples / Common / d3dAnimation.cls next >
Text File  |  2001-10-08  |  18KB  |  573 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "CD3DAnimation"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14.  
  15. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  16. '
  17. '  Copyright (C) 1999-2001 Microsoft Corporation.  All Rights Reserved.
  18. '
  19. '  File:       D3DAnimation.cls
  20. '  Content:    D3D Visual Basic Framework Animation Class
  21. '
  22. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  23.  
  24. Option Explicit
  25.  
  26. Public ObjectName As String
  27.  
  28. Private Type KEYHEADER
  29.     keytype As Long
  30.     keycount As Long
  31. End Type
  32.  
  33. Private Type RMROTATEKEY
  34.     time As Long
  35.     nFloats As Long
  36.     w As Single
  37.     x As Single
  38.     y As Single
  39.     z As Single
  40. End Type
  41.  
  42. Private Type D3DMATRIXKEY
  43.     time As Long
  44.     nFloats As Long
  45.     matrix As D3DMATRIX
  46. End Type
  47.  
  48.  
  49. Const kAnimGrowSize = 10
  50.  
  51. Dim m_RotateKeys() As D3DROTATEKEY
  52. Dim m_ScaleKeys() As D3DVECTORKEY
  53. Dim m_PositionKeys() As D3DVECTORKEY
  54. Dim m_RMRotateKeys() As RMROTATEKEY
  55. Dim m_MatrixKeys() As D3DMATRIXKEY
  56.  
  57. Dim m_NumRotateKeys As Long
  58. Dim m_NumScaleKeys As Long
  59. Dim m_NumPositionKeys As Long
  60. Dim m_NumMatrixKeys As Long
  61. Dim m_strFrameName As String
  62. Dim m_frame As CD3DFrame
  63. Dim m_iMatrixKey As Long
  64.  
  65.  
  66. Dim m_Children() As CD3DAnimation
  67. Dim m_NumChildren As Long
  68. Dim m_MaxChildren As Long
  69.  
  70. '-----------------------------------------------------------------------------
  71. ' Name: ParseAnimSet
  72. ' Desc: called from D3DUtil_LoadFromFile
  73. '-----------------------------------------------------------------------------
  74. Friend Sub ParseAnimSet(FileData As DirectXFileData, parentFrame As CD3DFrame)
  75.     On Local Error Resume Next
  76.     ObjectName = FileData.GetName()
  77.     
  78.     Dim ChildData As DirectXFileData
  79.     Dim NewAnim As CD3DAnimation
  80.     Dim ChildObj As DirectXFileObject
  81.     Dim ChildRef As DirectXFileReference
  82.     
  83.     Set ChildObj = FileData.GetNextObject()
  84.     
  85.      Do While Not ChildObj Is Nothing
  86.     
  87.         Set ChildData = ChildObj
  88.         If Err.Number = 0 Then
  89.   
  90.             If ChildData.GetType = "TID_D3DRMAnimation" Then
  91.                 Set NewAnim = New CD3DAnimation
  92.                 AddChild NewAnim
  93.                 NewAnim.ParseAnim ChildData, Me, parentFrame
  94.             End If
  95.         End If
  96.         
  97.         Err.Clear
  98.         Set ChildRef = ChildObj
  99.         
  100.         If Err.Number = 0 Then
  101.             Set ChildData = ChildRef.Resolve
  102.            
  103.             Set NewAnim = New CD3DAnimation
  104.             AddChild NewAnim
  105.             NewAnim.ParseAnim ChildData, Me, parentFrame
  106.         End If
  107.         
  108.         Err.Clear
  109.         
  110.         Set ChildObj = FileData.GetNextObject()
  111.     Loop
  112.     
  113. End Sub
  114.  
  115. '-----------------------------------------------------------------------------
  116. ' Name: GetChild
  117. ' Desc: return child Animation
  118. '-----------------------------------------------------------------------------
  119.  
  120. Public Function GetChild(i As Long) As CD3DAnimation
  121.     Set GetChild = m_Children(i)
  122. End Function
  123.  
  124. '-----------------------------------------------------------------------------
  125. ' Name: GetChildCount
  126. ' Desc: return number of child animations
  127. '-----------------------------------------------------------------------------
  128.  
  129. Public Function GetChildCount() As Long
  130.     GetChildCount = m_NumChildren
  131. End Function
  132.  
  133.  
  134. '-----------------------------------------------------------------------------
  135. ' Name: AddChild
  136. ' Desc: Add child animation
  137. '-----------------------------------------------------------------------------
  138.  
  139. Public Sub AddChild(child As CD3DAnimation)
  140.     If child Is Nothing Then Exit Sub
  141.     
  142.     If m_MaxChildren = 0 Then
  143.         m_MaxChildren = kAnimGrowSize
  144.         ReDim m_Children(m_MaxChildren)
  145.     ElseIf m_NumChildren >= m_MaxChildren Then
  146.         m_MaxChildren = m_MaxChildren + kAnimGrowSize
  147.         ReDim Preserve m_Children(m_MaxChildren)
  148.     End If
  149.     
  150.     Set m_Children(m_NumChildren) = child
  151.     m_NumChildren = m_NumChildren + 1
  152. End Sub
  153.  
  154.  
  155. '-----------------------------------------------------------------------------
  156. ' Name: SetFrame
  157. ' Desc: set Frame to be animated
  158. '-----------------------------------------------------------------------------
  159. Public Sub SetFrame(frame As CD3DFrame)
  160.     Set m_frame = frame
  161.     m_strFrameName = frame.ObjectName
  162. End Sub
  163.  
  164. '-----------------------------------------------------------------------------
  165. ' Name: GetFrame
  166. ' Desc: return frame being animated
  167. '-----------------------------------------------------------------------------
  168. Public Function GetFrame() As CD3DFrame
  169.     Set GetFrame = m_frame
  170. End Function
  171.  
  172.  
  173. '-----------------------------------------------------------------------------
  174. ' Name: ParseAnim
  175. ' Desc: Called by ParseAnimSet
  176. '-----------------------------------------------------------------------------
  177.  
  178. Friend Sub ParseAnim(FileData As DirectXFileData, parentAnimation As CD3DAnimation, parentFrame As CD3DFrame)
  179.     On Local Error Resume Next
  180.     ObjectName = FileData.GetName()
  181.     
  182.     Dim dataSize As Long
  183.     Dim KeyHead As KEYHEADER
  184.     Dim size As Long
  185.     Dim newFrame As CD3DFrame
  186.     Dim ChildObj As DirectXFileObject
  187.     Dim ChildData As DirectXFileData
  188.     Dim ChildReference As DirectXFileReference
  189.     Dim strChunkType As String
  190.     Dim i As Long
  191.     
  192.     Set ChildObj = FileData.GetNextObject()
  193.     
  194.     Do While Not ChildObj Is Nothing
  195.     
  196.         Set ChildReference = ChildObj
  197.         If Err.Number = 0 Then
  198.         
  199.             Set ChildData = ChildReference.Resolve()
  200.                     
  201.             
  202.             If ChildData.GetType = "TID_D3DRMFrame" Then
  203.                 m_strFrameName = ChildData.GetName()
  204.                 Set m_frame = parentFrame.FindChildObject(m_strFrameName, 0)
  205.             End If
  206.             
  207.             Set ChildReference = Nothing
  208.         End If
  209.         Err.Clear
  210.         
  211.         Set ChildData = ChildObj
  212.         If Err.Number = 0 Then
  213.         
  214.             strChunkType = ChildData.GetType
  215.             Select Case strChunkType
  216.                 Case "TID_D3DRMFrame"
  217.                     Set newFrame = New CD3DFrame
  218.                     newFrame.InitFromXOF g_dev, ChildData, parentFrame
  219.                     Set newFrame = Nothing
  220.                 
  221.                 Case "TID_D3DRMAnimationOptions"
  222.                     
  223.                 Case "TID_D3DRMAnimationKey"
  224.                     dataSize = ChildData.GetDataSize("")
  225.                     ChildData.GetDataFromOffset "", 0, 8, KeyHead
  226.  
  227.                     Select Case KeyHead.keytype
  228.                         Case 0      'ROTATEKEY
  229.                             ReDim m_RMRotateKeys(KeyHead.keycount)
  230.                             ReDim m_RotateKeys(KeyHead.keycount)
  231.                             size = Len(m_RMRotateKeys(0)) * KeyHead.keycount
  232.                             ChildData.GetDataFromOffset "", 8, size, m_RMRotateKeys(0)
  233.                             m_NumRotateKeys = KeyHead.keycount
  234.                             
  235.                             'NOTE x files are w x y z and QUATERNIONS are x y z w
  236.                             'so we loop through on load and copy the values
  237.                             For i = 0 To m_NumRotateKeys - 1
  238.                                 With m_RotateKeys(i)
  239.                                     .time = m_RMRotateKeys(i).time
  240.                                     If g_InvertRotateKey Then
  241.                                         .quat.w = -m_RMRotateKeys(i).w
  242.                                     Else
  243.                                         .quat.w = m_RMRotateKeys(i).w
  244.                                     End If
  245.                                     .quat.x = m_RMRotateKeys(i).x
  246.                                     .quat.y = m_RMRotateKeys(i).y
  247.                                     .quat.z = m_RMRotateKeys(i).z
  248.                                 End With
  249.                             Next
  250.                             ReDim m_RMRotateKeys(0)
  251.                             
  252.                         Case 1      'SCALE KEY
  253.                             ReDim m_ScaleKeys(KeyHead.keycount)
  254.                             size = Len(m_ScaleKeys(0)) * KeyHead.keycount
  255.                             ChildData.GetDataFromOffset "", 8, size, m_ScaleKeys(0)
  256.                             m_NumScaleKeys = KeyHead.keycount
  257.                 
  258.                         Case 2      'POSITION KEY
  259.                             ReDim m_PositionKeys(KeyHead.keycount)
  260.                             size = Len(m_PositionKeys(0)) * KeyHead.keycount
  261.                             ChildData.GetDataFromOffset "", 8, size, m_PositionKeys(0)
  262.                             m_NumPositionKeys = KeyHead.keycount
  263.                             
  264.                         Case 4      'MATRIX KEY
  265.                             ReDim m_MatrixKeys(KeyHead.keycount)
  266.                             size = Len(m_MatrixKeys(0)) * KeyHead.keycount
  267.                             ChildData.GetDataFromOffset "", 8, size, m_MatrixKeys(0)
  268.                             m_NumMatrixKeys = KeyHead.keycount
  269.                             
  270.                 End Select
  271.  
  272.                     
  273.             End Select
  274.         End If
  275.                     
  276.         Set ChildData = Nothing
  277.         Set ChildReference = Nothing
  278.         
  279.         Set ChildObj = FileData.GetNextObject()
  280.     Loop
  281.           
  282.  
  283.  
  284. End Sub
  285.  
  286.  
  287.  
  288. '-----------------------------------------------------------------------------
  289. ' Name: ComputeP1234
  290. ' Desc: Aux function to compute 4 nearest keys
  291. '-----------------------------------------------------------------------------
  292. Private Sub ComputeP1234(j As Long, maxNum As Long, ByRef p1 As Long, ByRef p2 As Long, ByRef p3 As Long, ByRef p4 As Long)
  293.  
  294.         p1 = j: p2 = j: p3 = j: p4 = j
  295.             
  296.             If j > 0 Then
  297.                 p1 = j - 2: p2 = j - 1
  298.             End If
  299.             If j = 1 Then
  300.                 p1 = j - 1: p2 = j - 1
  301.             End If
  302.             If j < (maxNum) - 1 Then p4 = j + 1
  303. End Sub
  304.         
  305.         
  306. '-----------------------------------------------------------------------------
  307. ' Name: SetTime
  308. ' Desc: Sets the matrix of the frame being animated
  309. '-----------------------------------------------------------------------------
  310. Public Sub SetTime(t As Single)
  311.     Dim t2 As Single
  312.     Dim i As Long, j As Long
  313.     Dim p1 As Long, p2 As Long, p3 As Long, p4 As Long
  314.     Dim f1 As Single, f2 As Single, f3 As Single, f4 As Single
  315.     Dim rM As D3DMATRIX, rQuat As D3DQUATERNION, rPos As D3DVECTOR, rScale As D3DVECTOR
  316.  
  317.     Dim a As D3DVECTOR, b As D3DVECTOR
  318.     Dim q1 As D3DQUATERNION, q2 As D3DQUATERNION
  319.     Dim s As Single
  320.     
  321.     Dim child As CD3DAnimation
  322.     Dim LastT As Single
  323.     
  324.     'Check children
  325.     For i = 1 To m_NumChildren
  326.         Set child = m_Children(i - 1)
  327.         If Not child Is Nothing Then
  328.             child.SetTime t
  329.         End If
  330.         Set child = Nothing
  331.     Next
  332.         
  333.     If m_frame Is Nothing Then Exit Sub
  334.     
  335.     'set components to identity  incase we dont have any keys.
  336.     D3DXMatrixIdentity rM
  337.     rScale = vec3(1, 1, 1)
  338.     
  339.     D3DXQuaternionIdentity rQuat
  340.         
  341.     
  342.     t2 = t
  343.     
  344.     'loop matrix keys
  345.     If m_NumMatrixKeys > 0 Then
  346.         t2 = t
  347.         LastT = m_MatrixKeys(m_NumMatrixKeys - 1).time
  348.         If t > LastT Then
  349.             i = t \ LastT
  350.             t2 = t - i * LastT
  351.         Else
  352.             
  353.         End If
  354.        
  355.        
  356.         'optimizations
  357.         Dim tAt As Single, tNext1 As Single, tNext2 As Single
  358.         
  359.         If m_iMatrixKey < m_NumMatrixKeys - 2 Then
  360.             tAt = m_MatrixKeys(m_iMatrixKey).time
  361.             tNext1 = m_MatrixKeys(m_iMatrixKey + 1).time
  362.             tNext2 = m_MatrixKeys(m_iMatrixKey + 2).time
  363.             If tAt < t2 And t2 <= tNext1 Then Exit Sub
  364.                
  365.             If tNext1 < t2 And t2 <= tNext2 Then
  366.                m_iMatrixKey = m_iMatrixKey + 1
  367.                If m_iMatrixKey > m_NumMatrixKeys Then m_iMatrixKey = 0
  368.                m_frame.SetMatrix m_MatrixKeys(m_iMatrixKey).matrix
  369.             End If
  370.  
  371.         End If
  372.         
  373.         'linear search
  374.         For i = 1 To m_NumMatrixKeys
  375.             If m_MatrixKeys(i - 1).time > t2 Then
  376.                 m_frame.SetMatrix m_MatrixKeys(i - 1).matrix
  377.                 m_iMatrixKey = i - 1
  378.            
  379.                 Exit Sub
  380.             End If
  381.         Next
  382.         
  383.      End If
  384.     
  385.     '.................
  386.     
  387.     
  388.     'loop position keys
  389.     If m_NumPositionKeys > 0 Then
  390.         t2 = t
  391.         LastT = m_PositionKeys(m_NumPositionKeys - 1).time
  392.         If t > LastT Then
  393.             i = t \ LastT
  394.             t2 = t - i * LastT
  395.         End If
  396.     End If
  397.     
  398.     'Check Position Keys
  399.     For i = 1 To m_NumPositionKeys
  400.         j = i - 1
  401.         
  402.         If m_PositionKeys(j).time > t2 Then
  403.                 
  404.             ComputeP1234 j, m_NumPositionKeys, p1, p2, p3, p4
  405.             f1 = m_PositionKeys(p1).time
  406.             f2 = m_PositionKeys(p2).time
  407.             f3 = m_PositionKeys(p3).time
  408.             f4 = m_PositionKeys(p4).time
  409.                             
  410.                 
  411.             If ((f3 - f2) = 0) Then
  412.                 s = 1
  413.             Else
  414.                 s = (t2 - f2) / (f3 - f2)
  415.             End If
  416.     
  417.             a = m_PositionKeys(p2).vec
  418.             b = m_PositionKeys(p3).vec
  419.             
  420.             
  421.             D3DXVec3Lerp rPos, a, b, s
  422.             Exit For
  423.         End If
  424.     Next
  425.         
  426.         
  427.         
  428.     'loop scale keys
  429.     If m_NumScaleKeys > 0 Then
  430.         t2 = t
  431.         LastT = m_ScaleKeys(m_NumScaleKeys - 1).time
  432.         If t > LastT Then
  433.             i = t \ LastT
  434.             t2 = t - i * LastT
  435.         End If
  436.     End If
  437.         
  438.         
  439.     'Check Scale Keys
  440.     For i = 1 To m_NumScaleKeys
  441.         j = i - 1
  442.         If m_ScaleKeys(j).time > t2 Then
  443.                 
  444.             ComputeP1234 j, m_NumScaleKeys, p1, p2, p3, p4
  445.             f1 = m_ScaleKeys(p1).time
  446.             f2 = m_ScaleKeys(p2).time
  447.             f3 = m_ScaleKeys(p3).time
  448.             f4 = m_ScaleKeys(p4).time
  449.                 
  450.             If ((f3 - f2) = 0) Then
  451.                 s = 1
  452.             Else
  453.                 s = (t2 - f2) / (f3 - f2)
  454.             End If
  455.     
  456.             a = m_ScaleKeys(p2).vec
  457.             b = m_ScaleKeys(p3).vec
  458.             
  459.             
  460.             D3DXVec3Lerp rScale, a, b, s
  461.             Exit For
  462.         End If
  463.     Next
  464.         
  465.  
  466.     'loop rotate keys
  467.     If m_NumRotateKeys > 0 Then
  468.         t2 = t
  469.         LastT = m_RotateKeys(m_NumRotateKeys - 1).time
  470.         If t > LastT Then
  471.             i = t \ LastT
  472.             t2 = t - i * LastT
  473.         End If
  474.     End If
  475.                 
  476.     'Check Rotate Keys
  477.     For i = 1 To m_NumRotateKeys
  478.         j = i - 1
  479.             
  480.         If m_RotateKeys(j).time > t2 Then
  481.             
  482.             
  483.             
  484.             ComputeP1234 j, m_NumRotateKeys, p1, p2, p3, p4
  485.             f1 = m_RotateKeys(p1).time
  486.             f2 = m_RotateKeys(p2).time
  487.             f3 = m_RotateKeys(p3).time
  488.             f4 = m_RotateKeys(p4).time
  489.                 
  490.             If ((f3 - f2) = 0) Then
  491.                 s = 1
  492.             Else
  493.                 s = (t2 - f2) / (f3 - f2)
  494.             End If
  495.     
  496.             q1 = m_RotateKeys(p2).quat
  497.             q2 = m_RotateKeys(p3).quat
  498.             
  499.             D3DXQuaternionSlerp rQuat, q1, q2, s
  500.             Exit For
  501.         End If
  502.     Next
  503.         
  504.     Dim temp1 As D3DMATRIX
  505.     Dim temp2 As D3DMATRIX
  506.     Dim temp3 As D3DMATRIX
  507.     
  508.     D3DXMatrixScaling temp1, rScale.x, rScale.y, rScale.z
  509.     D3DXMatrixRotationQuaternion temp2, rQuat
  510.     D3DXMatrixTranslation temp3, rPos.x, rPos.y, rPos.z
  511.     D3DXMatrixMultiply rM, temp1, temp2
  512.     D3DXMatrixMultiply rM, rM, temp3
  513.         
  514.     m_frame.SetMatrix rM
  515.     
  516. End Sub
  517.  
  518.  
  519. '-----------------------------------------------------------------------------
  520. ' Name: AddRotateKey
  521. ' Desc:
  522. '-----------------------------------------------------------------------------
  523.  
  524. Sub AddRotateKey(t As Long, quat As D3DQUATERNION)
  525.  
  526.     ReDim Preserve m_RotateKeys(m_NumRotateKeys)
  527.                    
  528.     With m_RotateKeys(m_NumRotateKeys)
  529.         .time = t
  530.         .quat = quat
  531.     End With
  532.     m_NumRotateKeys = m_NumRotateKeys + 1
  533. End Sub
  534.  
  535. '-----------------------------------------------------------------------------
  536. ' Name: AddScaleKey
  537. ' Desc:
  538. '-----------------------------------------------------------------------------
  539.                             
  540. Sub AddScaleKey(t As Long, scalevec As D3DVECTOR)
  541.  
  542.     ReDim Preserve m_ScaleKeys(m_NumScaleKeys)
  543.     
  544.     
  545.                    
  546.     With m_ScaleKeys(m_NumScaleKeys)
  547.         .time = t
  548.         .vec = scalevec
  549.     End With
  550.     
  551.     m_NumScaleKeys = m_NumScaleKeys + 1
  552. End Sub
  553.                         
  554. '-----------------------------------------------------------------------------
  555. ' Name: AddPositionKey
  556. ' Desc:
  557. '-----------------------------------------------------------------------------
  558. Sub AddPositionKey(t As Long, posvec As D3DVECTOR)
  559.  
  560.     ReDim Preserve m_PositionKeys(m_NumPositionKeys)
  561.     
  562.    
  563.                    
  564.     With m_PositionKeys(m_NumPositionKeys)
  565.         .time = t
  566.         .vec = posvec
  567.     End With
  568.     m_NumPositionKeys = m_NumPositionKeys + 1
  569. End Sub
  570.  
  571.  
  572.  
  573.